/*
 * TPublic()
 */
/** \file tpublic.prg
 *  \brief Clase para el reemplazo de variables publicas.
 */
/**
 *	Para acceder al valor de una variable, se puede hacer de 2 formas,
 *	una directa usando oPub:Get("Codigo") o por Prueba/Error oPub:Codigo,
 *	este último es mas simple de usar pero más lento.
 *
 *	Para definir un nuevo valor a una variable tambien puede ser por 2 formas,
 *	directamente por oPub:Set("Codigo", "ABC" ), o por Prueba/Error
 *	oPub:Codigo := "ABC".
 *
 *	Las variables definidas <b>NO</b> son <em>case sensitive</em>.
 *
 *  EJEMPLO
 *  \code_hb
 *	FUNCTION Test()
 *	local oP := TPublic():New(), aSave, nPos
 *
 *	oP:Add("Codigo")     // Defino variable sin valor inicial
 *	oP:Add("Precio", 1.15)     // Defino variable con valor inicial
 *	oP:Add("Cantidad", 10 )
 *	oP:Add("TOTAL" )
 *
 *	// Acceso a variables por prueba/error
 *	oP:Total := oP:Precio * oP:Cantidad
 *
 *	// Definicion y Acceso a variables directamente
 *	oP:Set("Total", oP:Get("precio") * oP:Get("CANTIDAD") )
 *
 *	oP:Del("Total")         // Borro una variable
 *	? oP:IsDef("TOTAL")     // Verifico si existe una variable
 *
 *	nPos := oP:GetPos("Total") // Obtengo la posición en el array
 *
 *	oP:Release()         // Borro TODAS las variables
 *
 *	oP:End()       // Termino
 *
 *	RETURN NIL
 *  \endcode_hb
 *
 *  EJEMPLO (Asignación Automática)
 *
 *  \code_hb
 *	FUNCTION MAIN()
 *	LOCAL oP:=TPublic():New(.T.)
 *
 *	op:nome		:= "Wilson Alves"
 *	op:Endereco	:= "Rua dos Cravos,75"
 *	op:Cidade	:= "Londrina-PR"
 *	op:Celular	:= "9112-5495"
 *	op:Empresa	:= "WCW Software"
 *
 *	? op:Nome,op:Endereco,op:Cidade,op:celular,op:empresa
 *
 *	op:End()
 *	RETURN NIL
 *  \endcode_hb
 *
 *  \author Daniel Andrade. 
 *  <br><em>andrade_2knews@hotmail.com</em>
 *  <br>Rosario - Santa Fe - Argentina
 */
/** 
 * \todo Falta mejorar la autocreacion de variables...  
 */

#include "gclass.ch"
#include "hbclass.ch"

CLASS TPublic

   VISIBLE:

   DATA  lAutoAdd    AS LOGICAL	 INIT .T.		
   DATA  lSensitive  AS LOGICAL	 INIT .F.		

//   DATA  hVars

//   DATA  nPos        AS NUMERIC    INIT 0   // READONLY // [ER]
//   DATA  cName       AS CHARACTER  INIT ""  // READONLY // [ER]

   METHOD New( lAutoAdd, lSensitive )   
   METHOD End()            INLINE ::Release()

   /** \brief Adiciona Variable al Objeto. */
   METHOD Add( cName, xValue )  

   /** \brief Elimina Variable del Objeto. */
   METHOD Del( cName )             

   /** \brief Obtiene el Valor de la Variable en el Objeto */
   METHOD Get( cName ) 

   /** \brief Asigna el Valor xValue a la Variable cName en el Objeto */
   METHOD Set( cName, xValue )

   /** \brief Adiciona Metodo "cMethod" al Objeto. */
   METHOD AddMethod( cMethod )

   /** \brief Elimina el Metodo indicado (<i>cMethod</i>) del Objeto. */
   METHOD DelMethod( cMethod )

   /** \brief Retorna .t. si la Variable cName está definida en el Objeto */
   METHOD IsDef( cName )   INLINE __objHasData( Self, cName )

   METHOD SendMsg()

//   METHOD GetPos( cName )
//   METHOD GetVar( nPos )

//   METHOD Clone()          INLINE HClone( ::hVars )
//   METHOD nCount()         INLINE Len( ::hVars )

//   METHOD GetArray()           

   METHOD Release()        INLINE Self := NIL

   ERROR HANDLER OnError( cMsg, nError )

ENDCLASS


//------------------------------------------------//
METHOD New( lAutomatic ) CLASS TPublic
   DEFAULT lAutomatic:=.T.

   ::lAutoAdd  :=lAutomatic
RETURN Self


//------------------------------------------------//
METHOD Add( cName, xValue ) CLASS TPublic

   if !::lAutoAdd ; return .f. ; endif

   if !::IsDef(cName)
      __objAddData( Self, cName )

      if !HB_ISNIL(xValue)
          return ::Set(cName, xValue)
      endif 

   endif

RETURN .F.


//------------------------------------------------//
METHOD Del( cName ) CLASS TPublic
   if !::IsDef(cName)
      __objDelMethod( Self, cName )
      return .t.
   endif
Return .f.


//------------------------------------------------//
METHOD Get( cName ) CLASS TPublic
   //local aData, nPos
   if ::IsDef(cName)
      return ::SendMsg( "_"+cName )
   endif
/*
   if __objHasData( Self, cName )
      aData := __objGetValueList(Self)
      nPos  := ASCAN(aData,{|a| a[HB_OO_DATA_SYMBOL]=UPPER(cName) }) 
      return aData[nPos,HB_OO_DATA_VALUE]
   endif
*/
Return nil


//------------------------------------------------//
METHOD Set( cName, xValue ) CLASS TPublic
   local uRet
   
   if __objHasData( Self, cName)

   #ifndef __XHARBOUR__
      if xValue == nil
         uRet = __ObjSendMsg( Self, cName )
      else
         __objSendMsg( Self, "___"+cName, __objSendMsg(Self,cName) )
         uRet = __ObjSendMsg( Self, "_"+cName, xValue )
      endif
   #else   
      if xValue == nil
         uRet = hb_execFromArray( @Self, cName )
      else
         hb_execFromArray( @Self, "___"+cName, ;
                           { hb_execFromArray( @Self,cName) } )
         uRet = hb_execFromArray( @Self, cName, { xValue } )
      endif
   #endif    

   endif

return nil


//------------------------------------------------//
METHOD AddMethod( cMethod, pFunc ) CLASS TPublic
 
   if ! __objHasMethod( Self, cMethod )  
      __objAddMethod( Self, cMethod, pFunc )    
   endif

return nil


//------------------------------------------------//
METHOD DelMethod( cMethod ) CLASS TPublic
 
   if ! __objHasMethod( Self, cMethod )  
      __objDelMethod( Self, cMethod )    
   endif

return nil


//------------------------------------------------//

#ifndef __XHARBOUR__
METHOD SendMsg( cMsg, ...  ) CLASS TPublic
   if "(" $ cMsg
      cMsg = StrTran( cMsg, "()", "" )
   endif
return __ObjSendMsg( Self, cMsg, ... )
#else   
METHOD SendMsg( ... ) CLASS TPublic
   local aParams := hb_aParams()
      
   if "(" $ aParams[ 1 ]
      aParams[ 1 ] = StrTran( aParams[ 1 ], "()", "" )
   endif
 
   ASize( aParams, Len( aParams ) + 1 )
   AIns( aParams, 1 )
   aParams[ 1 ] = Self
   
   return hb_execFromArray( aParams )   
#endif 


//------------------------------------------------//
METHOD ONERROR( uParam1 ) CLASS TPublic
   local cCol    := __GetMessage()

   if Left( cCol, 1 ) == "_"
      cCol = Right( cCol, Len( cCol ) - 1 )
   endif
   
   if !::IsDef(cCol)
      ::Add( cCol )
   endif
   
RETURN ::Set(cCol,uParam1)

//EOF
